﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Threading;

namespace TaskManager
{
    public class AsynQueue<T>
    {
        private bool isOpen = true;
        private List<T> list = new List<T>();

        public void Add(T data)
        {
            lock (list)
                list.Add(data);
        }

        public void Remove(T data)
        {
            lock (list)
                list.Remove(data);
        }

        public void RemoveAll(Predicate<T> match)
        {
            lock (list)
                list.RemoveAll(match);
        }

        public void Close()
        {
            lock (list)
                isOpen = false;
        }

        public bool Pop(out T data)
        {
            lock (list)
            {
                if (list.Count > 0)
                {
                    data = list.FirstOrDefault();
                    list.Remove(data);

                    return true;
                }
                else
                {
                    data = default(T);
                    return false;
                }
            }
        }

        public bool WaitPop(out T data)
        {
            var isFind = false;
            Monitor.Enter(list);

            while (isOpen && list.Count == 0)
                Monitor.Wait(list);

            if (list.Count > 0)
            {
                data = list.First();
                list.Remove(data);
                isFind = true;
            }
            else
            {
                data = default(T);
            }

            Monitor.Exit(list);

            return isFind;
        }
    }
}
